<?php

namespace Library;
use Think\Log;

/**
 * 卡券操作累
 */
class CardCode {
    private static $_instance;
    protected $card_model;
    private $cards_list_model;
    private $prizes_order_model;
	private function __construct() {
        $this->card_model = D('card');
		$this->cards_list_model = D("cards_list");
        $this->prizes_order_model = D('prizes_order');
	}

    public function __clone(){
        trigger_error('Clone is not allow!', E_USER_ERROR);
    }

    public static function getInstance(){
        if (!(self::$_instance instanceof self)) {
            self::$_instance = new self;
        }
        return self::$_instance;
    }

    /**
     * 生成12位的数字作为Code， 微信的库存数量限制为100000000
     * @param int $materials_id 物料id
     * @param int $card_num 卡券数量
     * @return array
     */
    public function create_cards($materials_id, $card_num) {
        //以后可以修改为在存储过程中生存卡券号码
        if (empty($card_num)) {
            return FALSE;
        }
        for ($i=0; $i<$card_num; $i++) {
            $card = sprintf('%05d%03d%03d', mt_rand(0, 99999), mt_rand(0, 999), mt_rand(0, 999));
        	$data['card_id'] = $materials_id;
            $data['card_number'] = $card.self::calcIDCardCode($card);
        	$data['created_at'] = date("Y-m-d H:i:s",time());
        	$this->cards_list_model->add($data);
        }
    }

     /*
     *  获取红包金额
     */
    public function get_hb_amount($card_id) {
        $this->card_model->startTrans();

        try {
            $result = TRUE;
            $money = 0;
            $where['id'] = $card_id;
            $card = $this->card_model->lock(true)->where($where)->find();

            $balance = $card['card_count'] - $card['card_get_count'];
            if ($balance > 0) {
                $money = mt_rand($card['min_money'], $card['max_money']);
                if ($money > $balance) {
                    $money = $balance;
                }
                $this->card_model->where('id= '.$card_id)->setInc('card_get_count', $money);
            } else {
                \Think\Log::record('get_hb_amount balance is zero');
            }
        } catch (\Exception $exc) {
            $result = FALSE;
            \Think\Log::record('get_hb_amount catch Exception'.$exc->getMessage());
        }

        if ($result){
            //提交事务
            $this->card_model->commit();
        }else{
           // 事务回滚
           $this->card_model->rollback();
           \Think\Log::record('get_card $card_id fail rollback');
        }

        \Think\Log::record('get_hb_amount card_id:'.$card_id.':money'.$money);
        return $money;
    }

    /**
     * 释放一个未使用的红包
     */
    public function free_hb($card_id, $money) {

        $this->card_model->startTrans();
        try {
            $this->card_model->where('id= '.$card_id)->setDec('card_get_count', $money);
            \Think\Log::record('free_hb card_id:'.$card_id.':money'.$money);
            $this->card_model->commit();

            return true;
        } catch (\Exception $exc) {
            \Think\Log::record('free_hb:'.$exc->getTraceAsString());
            $this->card_model->rollback();
        }
        return false;
    }

    /**
     * 随机获取一个未使用的卡券
     */
    public function get_card($card_id) {
        $this->card_model->startTrans();

        try {
            $result = TRUE;
            $code_code = '';
            $where['id'] = $card_id;
            $where['card_status'] = 0;
            $card = $this->card_model->lock(true)->where('id = "'.$card_id.'"')->find();

            \Think\Log::record('get_card $card is:'. json_encode($card));
            $balance = $card['card_count'] - $card['card_get_count'];
            if ($balance > 0) {
                $code_code = $this->cards_list_model->lock(true)->where("card_status=0 and card_id=$card_id")->find();

                if ($code_code) {
                    $data['card_status'] = 1;
                    $data['updated_at'] = date("Y-m-d H:i:s",time());
                    $this->cards_list_model->where('id = "'.$code_code['id'].'"')->save($data);
                    $this->card_model->lock(true)->where('id= '.$card_id)->setInc('card_get_count', 1);
                    \Think\Log::record('get_card $code_code is:'. json_encode($code_code));
                } else {
                    \Think\Log::record('get_card code_code num zero');
                }
            } else {
                \Think\Log::record('get_card balance is zero');
            }
        } catch (\Exception $exc) {
            $result = FALSE;
            \Think\Log::record('get_card catch Exception'.$exc->getMessage());
        }

        if ($result){
            //提交事务
            $this->card_model->commit();
        }else{
           // 事务回滚
           $this->card_model->rollback();
        }

        \Think\Log::record('get_card card_id: '.$card_id.':code_code: '. json_encode($code_code));
        return $code_code;
    }

    /**
     * 释放一个未使用的卡券
     */
    public function free_card($card_id, $card_list_id) {

        $this->card_model->startTrans();
        try {
            $data['card_status'] = 0;
            $data['updated_at'] = date("Y-m-d H:i:s",time());
            $this->cards_list_model->where('id = "'.$card_list_id.'"')->save($data);
            $this->card_model->where('id= '.$card_id)->setDec('card_get_count', 1);
            \Think\Log::record('free_card card_id:'.$card_id.':card_list_id'.$card_list_id);

            $this->card_model->commit();
            return true;
        } catch (\Exception $exc) {
            \Think\Log::record('free_card '.$exc->getTraceAsString());
            $this->card_model->rollback();
        }
        return false;
    }

    /*
     * 获取用户的所有卡券
     */
    public function getAllUserCard() {
        $user = \Library\User::getInstance();
        $sql = 'SELECT
                DISTINCT yy_card.id,
                    yy_card.card_name,
                    yy_card.card_icon,
                    yy_card.card_intro,
                    yy_prizes_order.card_num,
                    yy_prizes_order.winning_time
                FROM
                    yy_prizes_order
                    LEFT JOIN yy_card ON yy_prizes_order.card_id = yy_card.id
                WHERE
                    `yy_prizes_order` .`openid`  = "'.$user->getCurrentOpenId().'"
                     and (order_status = 1 or order_status = 2) order by yy_prizes_order.winning_time desc';
        $userCards = $this->prizes_order_model->query($sql);

        return $userCards;
    }

    /*
     * 获取卡券详细信息
     */
    public function getCardDetail($cardId, $cardCode) {
        if (!$cardCode) {
            return false;
        }
        $sql = 'SELECT 
                DISTINCT yy_card.id,
                    yy_card.card_name,
                    yy_prizes_order.order_status,
                    yy_card.worth,
                    yy_card.card_icon,
                    yy_card.card_intro,
                    yy_prizes_order.card_num,
                    yy_prizes_order.winning_time,
                    yy_card_detail.card_sdate,
                    yy_card_detail.card_edate,
                    yy_card_detail.open_time_type,
                    yy_card_detail.open_time_day,
                    yy_card_detail.open_time_period,
                    yy_card_detail.user_notice
                FROM 
                    yy_prizes_order 
                    LEFT JOIN yy_card ON yy_prizes_order.card_id = yy_card.id 
                    LEFT JOIN yy_card_detail ON yy_card_detail.card_id = yy_card.id 
                WHERE 
                    `yy_prizes_order` .`card_num`  = "'.$cardCode.'"
                     and (yy_prizes_order.order_status = 1 or yy_prizes_order.order_status = 2)';
        if ($cardId) {
            $sql .= ' and  yy_card.id  = '.$cardId.'';
        }
        $userCards = $this->prizes_order_model->query($sql);

        if (is_array($userCards)) {
            return $userCards[0];
        }
        return false;
    }

    /*
     * 领取卡券
     */
    public function getPrizes($card_list_code) {

        $this->card_model->startTrans();
        try {
            $user = \Library\User::getInstance();
            if ($user) {
                $data['order_status'] = 1;
                $data['send_time'] = date("Y-m-d H:i:s",time());

                $where['openid'] = $user->getCurrentOpenId();
                $where['card_num'] = $card_list_code;
                $where['order_status'] = 0;
                $where['send_time'] =  array('EXP','IS NULL');
                $this->prizes_order_model->where($where)->save($data);
                \Think\Log::record('getPrizes :card_list_code'.$card_list_code);

                $this->card_model->commit();
                return TRUE;
            }
        } catch (\Exception $exc) {
            \Think\Log::record('getPrizes '.$exc->getTraceAsString());
        }
        $this->card_model->rollback();
        return FALSE;
    }

    /**
     * 卡券删除
     */
    public function delete() {
        return true;
    }

    /**
     * 卡券投放
     */
    public function give() {
        return true;
    }

    /*
     * 检查卡券状态
     */
    public function checkConsume($cardId, $cardCode) {
        try {
            if ($cardId) {
                $where['card_id'] = $cardId;
            }
            $where['card_num'] = $cardCode;
            $code = $this->prizes_order_model->lock(true)->where($where)->find();
            \Think\Log::record(json_encode($code));
            if ($code && is_array($code)) {
                return $code['order_status'];
            }
        } catch (\Exception $exc) {
            \Think\Log::record('check_consume '.$exc->getTraceAsString());
        }
        return FALSE;
    }

    /*
     * 检查卡券核销密码
     */
    public function checkConsumeKey($cardId, $key) {
        try {
            $where['id'] = $cardId;
            $passwordList = $this->card_model->where($where)->getField('password');
            if ($passwordList) {
                $passwordArray = explode(',', $passwordList);
                Log::record(json_encode($passwordArray));
                if ($passwordArray && in_array($key, $passwordArray)) {
                    return TRUE;
                }
            }
        } catch (\Exception $exc) {
            \Think\Log::record('checkConsumeKey '.$exc->getTraceAsString());
        }
        return FALSE;
    }

    /**
     * 卡券核销
     */
    public function consume($cardId, $cardCode) {
        $this->card_model->startTrans();
        try {
            \Think\Log::record('consume '. $cardCode);
            if (!$this->checkConsume($cardId, $cardCode)) {
                return FALSE;
            }
            \Think\Log::record('consume 2');
            $data['order_status'] = 2;
            $data['use_time'] = date("Y-m-d H:i:s",time());
            if ($cardId) {
                $where['card_id'] = $cardId;
            }
            $where['order_status'] = 1;
            $where['card_num'] = $cardCode;
            $this->prizes_order_model->where($where)->save($data);
            \Think\Log::record('consume :cardCode: '.$cardCode);

            $this->card_model->commit();
            \Think\Log::record('consume 3');
            return TRUE;
        } catch (\Exception $exc) {
            \Think\Log::record('getPrizes '.$exc->getTraceAsString());
        }
        $this->card_model->rollback();
        return FALSE;
    }

    /**
     * 获取卡券号码列表
     */
    public function get_Cards() {
        return $card;
    }

    //验证是否有效
    private static function validateIDCard($IDCard) {
        if (strlen($IDCard) == 11) {
            return check18IDCard($IDCard);
        } else {
            return false;
        }
    }

    //计算最后一位验证码,根据国家标准GB 11643-1999
    private function calcIDCardCode($IDCardBody) {
        if (strlen($IDCardBody) != 11) {
            return false;
        }

        //加权因子
        $factor = array(4 ,5, 3, 8, 2, 1, 6, 7, 9, 5, 8);

        //校验码对应值
        $code = array('1', '0', '9', '8', '7', '6', '5', '4', '3', '2');
        $checksum = 0;

        for ($i = 0; $i < strlen($IDCardBody); $i++) {
            $checksum += substr($IDCardBody, $i, 1) * $factor[$i];
        }

        return $code[$checksum % 10];
    }

    //11位优惠券校验码有效性检查
    private function check12IDCard($IDCard) {
        if (strlen($IDCard) != 12) {
            return false;
        }

        $IDCardBody = substr($IDCard, 0, 11); //
        $IDCardCode = strtoupper(substr($IDCard, 11, 1)); //最后一位的验证码

        if (self::calcIDCardCode($IDCardBody) != $IDCardCode) {
            return false;
        } else {
            return true;
        }
    }
}

?>
